#include "servicecode/LoadWebPage.h"

LoadWebPage* LoadWebPage::_pInstance =new LoadWebPage();

LoadWebPage* LoadWebPage::getInstance()
{
    if(!_pInstance){
        _pInstance =new LoadWebPage();
    }
    return _pInstance;
}

LoadWebPage::LoadWebPage()
{
    try {
        LodoffsetLib("data/newoffsetLib.dat", _newoffset); 
        LodinvertIndexLib();
        _dataLoaded = true;
        LogInfo("数据加载完成");
    } catch(const std::exception& e) {
        LogError("数据加载失败: %s", e.what());
        _dataLoaded = false;
    }
}
//加载网页偏移库
void LoadWebPage::LodoffsetLib(const string &path, map<int, pair<int, int>> &off_set)
{
    LogInfo("加载网页偏移库");
    ifstream ifs(path);
    if (!ifs.is_open())
    {
        LogError("打开 %s 失败", path.c_str());
        throw std::runtime_error("无法打开偏移库文件");
    }
    string line;
    int id, offset, leng;
    while (getline(ifs, line))
    {
        istringstream iss(line);
        iss >> id;
        iss >> offset;
        iss >> leng;
        off_set[id] = {offset, leng};
    }
}
//加载倒排索引
void LoadWebPage::LodinvertIndexLib()
{
    LogInfo("加载倒排索引库");
    ifstream ifs("data/invertIndex.dat");
    if (!ifs.is_open())
    {
        LogError("打开 data/invertIndex.dat 失败");
        throw std::runtime_error("无法打开倒排索引文件");
    }
    string line,word;
    int id;
    double weight;
    while (getline(ifs, line))
    {
        istringstream iss(line);
        iss >> word;
        while(iss >> id >> weight)
        {
            _invertIndexLib[word][id] = weight;
        }
    }
}

// 从网页库中加载指定id的网页
bool LoadWebPage::LodPagefromLib(int id,WebPage & wbp)
{

    if (_newoffset.find(id) == _newoffset.end())
    {
        LogDebug("加载网页库,此id不存在:%d", id);
        return false;
    }

    int offset = _newoffset[id].first;
    int leng = _newoffset[id].second;

    ifstream ifs("data/newripepage.dat", std::ios::binary);
    if (!ifs.is_open())
    {
        LogError("打开 data/newripepage.dat 失败");
        exit(1);
    }
    ifs.seekg(offset);
    char *buffer = new char[leng + 1];
    ifs.read(buffer, leng);
    buffer[leng] = '\0'; // 将字符串的最后一个字节换成终止符

    // LogInfo("网页id:%d,偏移量：%d,长度：%d", id, offset, leng);
    //  LogDebug("%s",buffer);
    
    XMLDocument _xmldoc;//当多个线程同时执行xml解析时，使用同一个xml将导致资源冲突
    _xmldoc.Parse(buffer);
    if (_xmldoc.ErrorID())
    {
        LogError("加载网页时,xml解析出错 id:%d", id);
        return false;
    }

    XMLElement *itemNode = _xmldoc.FirstChildElement("doc");
    if (itemNode)
    {
        const char *docid = itemNode->FirstChildElement("docid")->GetText();
        if (docid)
        {
            wbp._id = atoi(docid);
        }
        else
        {
            wbp._id = 0;
        }
        const char *title = itemNode->FirstChildElement("title")->GetText();
        if (title)
        {
            wbp._title = title;
        }
        const char *link = itemNode->FirstChildElement("link")->GetText();
        if (link)
        {
            wbp._link = link;
        }
        const char *des = itemNode->FirstChildElement("description")->GetText();
        if (des)
        {
            wbp._description = des;
        }
        itemNode->NextSiblingElement("doc");
    }
    delete[] buffer;

    return true;
}